home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1997 February: Technology Seed / Mac Tech Seed Feb '97.toast / OpenDoc 1.2b2c1 / Implementation / Utilities / UseRsrcM.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  1997-02-13  |  9.7 KB  |  385 lines  |  [TEXT/MPS ]

  1. /*
  2.     File:        UseRsrcM.cpp
  3.  
  4.     Contains:    Functions for using resources from the resource fork of a library
  5.                 and others for loading resources into temp mem.
  6.  
  7.     Owned by:    Reggie Adkins
  8.  
  9.     Copyright:    © 1994 - 1996 by Apple Computer, Inc., all rights reserved.
  10.  
  11.          <3>      10/22/96    DH        1369514 Overhauled resource loading
  12.                                     functions so that a variety of places can
  13.                                     be searched for resources to load into temp
  14.                                     mem.
  15.  
  16.          <2>     6/21/96    DH        1353507: 1.0.x: Dragging Scrapbook OpenDoc
  17.                                     clipping to document can cause crash. Added
  18.                                     function to read a resource fork that takes
  19.                                     a fileRefNum
  20. */
  21.  
  22.  
  23. #ifndef _USERSRCM_
  24. #include "UseRsrcM.h"
  25. #endif
  26.  
  27. #ifndef __TEXTUTILS__
  28. #include <TextUtils.h>
  29. #endif
  30.  
  31. #ifndef _EXCEPT_
  32. #include "Except.h"
  33. #endif
  34.  
  35. #ifndef _ODDEBUG_
  36. #include "ODDebug.h"
  37. #endif
  38.  
  39. #ifndef _ODMEMORY_
  40. #include <ODMemory.h>
  41. #endif
  42.  
  43. #ifndef _PASCLSTR_
  44. #include <PasclStr.h>
  45. #endif
  46.  
  47. #ifndef __FRAGRSRC__
  48. #include <FragRsrc.h>
  49. #endif
  50.  
  51. #ifndef __RESOURCES__
  52. #include <Resources.h>
  53. #endif
  54.  
  55. #ifndef __ERRORS__
  56. #include <Errors.h>
  57. #endif
  58.  
  59.  
  60. static CFragResFileRef    gFragRef = kODNULL;        // Reference to resource map
  61. static short            gRefNum = -1;            // RefNum of resource file
  62. static ODSLong            gNesting = 0;            // Nesting level (>0 means in use)
  63.  
  64.  
  65. OSErr
  66. InitLibraryResources( CFragInitBlockPtr init )
  67. {
  68.     return InitCFragResources(init,&gFragRef);
  69. }
  70.  
  71.  
  72. void
  73. CloseLibraryResources( )
  74. {
  75.     if( gNesting>0 )
  76.         WARN("Resource file still in use while being closed!");
  77.     OSErr err= TermCFragResources(gFragRef);
  78.     if( err )
  79.         WARN("TermCFragResources returned %hd",err);
  80.     
  81.     gFragRef = kODNULL;
  82.     gRefNum = -1;
  83.     gNesting = 0;
  84. }
  85.  
  86.  
  87. ODSLong BeginUsingLibraryResources( )
  88. {
  89.     short ref = CurResFile();
  90.     if( gNesting > 0 )
  91.         UseResFile(gRefNum);
  92.     else {
  93.         THROW_IF_ERROR( BeginCFragResources(gFragRef) );
  94.         gRefNum = CurResFile();
  95.     }
  96.     gNesting++;
  97.     return ref;
  98. }
  99.  
  100.  
  101. void EndUsingLibraryResources( ODSLong ref )
  102. {
  103.     if( gNesting > 0 )
  104.         if( --gNesting == 0 )
  105.             THROW_IF_ERROR( EndCFragResources(gFragRef) );
  106.     UseResFile(ref);
  107. }
  108.  
  109.  
  110. CUsingLibraryResources::~CUsingLibraryResources( )
  111. {
  112.     ODSLong ref = fRefNum;
  113.     if( ref != -1 ) {                        // Make sure it's done only once
  114.         fRefNum = -1;
  115.         EndUsingLibraryResources(ref);
  116.     }
  117. }
  118.  
  119.  
  120. // RESOURCE UTILITIES:
  121.  
  122. //------------------------------------------------------------------------------
  123. // BasicReadResource
  124. //
  125. // This function loads the resource out of the part's library file or the OpenDocLib.
  126. // The advantage of using this function over the Mac Resource Mgr directly is
  127. // that this will load the resource into temp mem rather than the app heap.
  128. //------------------------------------------------------------------------------
  129.  
  130. static void*
  131. BasicReadResource( ResType type, short id, ConstStr255Param name, ODBoolean asHandle )
  132. {
  133.     void *result = kODNULL; ODVolatile(result);
  134.     
  135.     ODSLong savedRef = BeginUsingLibraryResources();
  136.     
  137.     TRY{
  138.         result = ReadResourceIntoTempMem( type, id, name, asHandle );
  139.     }CATCH_ALL{
  140.         EndUsingLibraryResources(savedRef);
  141.         RERAISE;
  142.     }ENDTRY
  143.     
  144.     EndUsingLibraryResources(savedRef);
  145.     return result;
  146. }
  147.  
  148.  
  149. //------------------------------------------------------------------------------
  150. // The following few utility functions will load resources into temp mem rather than
  151. // the app heap. The only limitation is that they will only load resources from your
  152. // part libray or the OpenDoc library. To load resources from arbitrary files, see the 
  153. // functions further down.
  154. //------------------------------------------------------------------------------
  155.  
  156. ODHandle
  157. ODReadResource( ResType type, short id )
  158. {
  159.     return (ODHandle) BasicReadResource(type,id,kODNULL,kODTrue);
  160. }
  161.  
  162. ODHandle
  163. ODReadNamedResource( ResType type, ConstStr255Param name )
  164. {
  165.     if( name==kODNULL )
  166.         THROW(kODErrIllegalNullInput);
  167.     return (ODHandle) BasicReadResource(type,0,name,kODTrue);
  168. }
  169.  
  170. ODPtr
  171. ODReadResourceToPtr( ResType type, short id )
  172. {
  173.     return BasicReadResource(type,id,kODNULL,kODFalse);
  174. }
  175.  
  176. ODPtr
  177. ODReadNamedResourceToPtr( ResType type, ConstStr255Param name )
  178. {
  179.     if( name==kODNULL )
  180.         THROW(kODErrIllegalNullInput);
  181.     return BasicReadResource(type,0,name,kODFalse);
  182. }
  183.  
  184.  
  185. void
  186. ODGetString( Str255 str, short id )
  187. {
  188.     str[0] = 0;
  189.     ODSLong savedRef = BeginUsingLibraryResources();
  190.     Handle h = Get1Resource('STR ',id);
  191.     OSErr result = ResError();
  192.     if( h ) {
  193.         CopyPascalString(str,(StringPtr)*h);
  194.         ReleaseResource(h);
  195.     }
  196.     EndUsingLibraryResources(savedRef);
  197.     if( !h ) {
  198.         THROW(result);
  199.         THROW(resNotFound);
  200.     }
  201. }
  202.  
  203.  
  204. void
  205. ODGetIndString( Str255 str, short id, short index )
  206. {
  207.     str[0] = 0;
  208.     ODSLong savedRef = BeginUsingLibraryResources();
  209.     Handle h = Get1Resource('STR#',id);
  210.     OSErr result = ResError();
  211.     if( h ) {
  212. #if ODDebug
  213.         if( index<1 || index>**(short**)h ) {
  214.             WARN("ODGetIndString(%hd,%hd): invalid index",id,index);
  215.             result= kODErrValueOutOfRange;
  216.         } else
  217. #endif
  218.         GetIndString(str,id,index);
  219.         ReleaseResource(h);
  220.     }
  221.     EndUsingLibraryResources(savedRef);
  222.     if( result ) {
  223.         THROW(result);
  224.         THROW(resNotFound);
  225.     }
  226. }
  227.  
  228. //------------------------------------------------------------------------------
  229. // ODReadResourceUsingRefnum
  230. //
  231. // This function takes a refnum to load the resource from. This is different than
  232. // the other resource loading functions because this one will only load the
  233. // resource from the resource fork pointed to by the refnum parameter, whereas
  234. // the original assumes it will load out of the part's library file or the OpenDocLib.
  235. // The advantage of using this function over the Mac Resource Mgr directly is
  236. // that this will load the resource into temp me rather than the app heap.
  237. //------------------------------------------------------------------------------
  238.  
  239. void*
  240. ODReadResourceUsingRefnum( short ResRefNum, ResType type, short id, ConstStr255Param name, ODBoolean asHandle )
  241. {
  242.     void *result = kODNULL; ODVolatile(result);
  243.     
  244.     short oldResRefnum; ODVolatile( oldResRefnum );
  245.     oldResRefnum = CurResFile();        // save the current start of the resource map.
  246.     UseResFile( ResRefNum );
  247.     
  248.     TRY{
  249.         ReadResourceIntoTempMem( type, id, name, asHandle );
  250.     }
  251.     CATCH_ALL{
  252.         UseResFile( oldResRefnum );        // restore the old start of the resource map
  253.         RERAISE;
  254.     }ENDTRY
  255.     
  256.     UseResFile( oldResRefnum );        // restore the old start of the resource map
  257.     
  258.     return result;
  259. }
  260.  
  261. //------------------------------------------------------------------------------
  262. // ReadResourceIntoTempMem
  263. //
  264. // Yet another resource loading function. When called directly will search the
  265. // entire resource chain for the specified resource rather than in a particular
  266. // refnum or in a particular library. Useful for loading resources from a
  267. // collection of files.
  268. // The advantage of using this function over the Mac Resource Mgr directly is
  269. // that this will load the resource into temp me rather than the app heap.
  270. //------------------------------------------------------------------------------
  271.  
  272. void* ReadResourceIntoTempMem( ResType type, short id, ConstStr255Param name, ODBoolean asHandle )
  273. {
  274.     Handle rsrc; ODVolatile(rsrc);
  275.     void *result = kODNULL; ODVolatile(result);
  276.  
  277.     SetResLoad(false);
  278.     if( name )
  279.         rsrc = Get1NamedResource(type,name);
  280.     else
  281.         rsrc = Get1Resource(type,id);
  282.     SetResLoad(true);
  283.     if( rsrc == kODNULL ) {
  284.         OSErr err = ResError();
  285.         THROW( err ? err : resNotFound );
  286.     }
  287.     
  288.     TRY{
  289.         ODSize size = (*rsrc) ?GetHandleSize(rsrc) :GetResourceSizeOnDisk(rsrc);
  290.         void *dst;
  291.         if( asHandle ) {
  292.             result = (void*) ODNewHandle(size);
  293.             dst = ODLockHandle((ODHandle)result);
  294.         } else
  295.             result = dst = ODNewPtr(size);
  296.     
  297.         if( *rsrc == kODNULL ) {
  298.             // Resource is not in memory, use partial-resource call:
  299.             ReadPartialResource( rsrc, 0, dst, size );
  300.             THROW_IF_ERROR( ResError() );
  301.             ReleaseResource(rsrc);
  302.         } else {
  303.             // Resource is already in memory; just copy it:
  304.             ODBlockMove(*rsrc,dst,size);
  305.         }
  306.  
  307.         if( asHandle )
  308.             ODUnlockHandle((ODHandle)result);
  309.  
  310.     }CATCH_ALL{
  311.         if( *rsrc == kODNULL )
  312.             ReleaseResource(rsrc);
  313.         if( result )
  314.             if( asHandle )
  315.                 ODDisposeHandle((ODHandle)result);
  316.             else
  317.                 ODDisposePtr(result);
  318.         RERAISE;
  319.     }ENDTRY
  320.     
  321.     return result;
  322. }
  323.  
  324. //------------------------------------------------------------------------------
  325. // ReadIndexedResourceIntoTempMem
  326. //
  327. // Has the same functionality as Get1IndResource, where given an index i, this
  328. // function will load the i'th resource of the number 1 to n of resources, where
  329. // n is returned by Count1Resources. When called directly will search the
  330. // entire resource chain for the specified resource rather than in a particular
  331. // refnum or in a particular library. Useful for loading all resources of a 
  332. // particular type.
  333. // The advantage of using this function over the Mac Resource Mgr directly is
  334. // that this will load the resource into temp me rather than the app heap.
  335. //------------------------------------------------------------------------------
  336.  
  337. void* ReadIndexedResourceIntoTempMem( ResType type, short index, ODBoolean asHandle )
  338. {
  339.     Handle rsrc; ODVolatile(rsrc);
  340.     void *result = kODNULL; ODVolatile(result);
  341.  
  342.     SetResLoad(false);
  343.     rsrc = Get1IndResource( type, index );
  344.     SetResLoad(true);
  345.     if( rsrc == kODNULL ) {
  346.         OSErr err = ResError();
  347.         THROW( err ? err : resNotFound );
  348.     }
  349.     
  350.     TRY{
  351.         ODSize size = (*rsrc) ?GetHandleSize(rsrc) :GetResourceSizeOnDisk(rsrc);
  352.         void *dst;
  353.         if( asHandle ) {
  354.             result = (void*) ODNewHandle(size);
  355.             dst = ODLockHandle((ODHandle)result);
  356.         } else
  357.             result = dst = ODNewPtr(size);
  358.     
  359.         if( *rsrc == kODNULL ) {
  360.             // Resource is not in memory, use partial-resource call:
  361.             ReadPartialResource( rsrc, 0, dst, size );
  362.             THROW_IF_ERROR( ResError() );
  363.             ReleaseResource(rsrc);
  364.         } else {
  365.             // Resource is already in memory; just copy it:
  366.             ODBlockMove(*rsrc,dst,size);
  367.         }
  368.  
  369.         if( asHandle )
  370.             ODUnlockHandle((ODHandle)result);
  371.  
  372.     }CATCH_ALL{
  373.         if( *rsrc == kODNULL )
  374.             ReleaseResource(rsrc);
  375.         if( result )
  376.             if( asHandle )
  377.                 ODDisposeHandle((ODHandle)result);
  378.             else
  379.                 ODDisposePtr(result);
  380.         RERAISE;
  381.     }ENDTRY
  382.     
  383.     return result;
  384. }
  385.